package edu.towson.cosc.cosc455.mdapice.compiler;

import java.util.ArrayList;

import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;

/**
 * COSC 455 Programming Languages: Implementation and Design.
 * 
 * A Simple Syntax Analyzer interfaced by Josh Dehlinger (2013) and
 * modified by Michelle D'Apice (2014).
 * 
 * Reads token by token from Lexical Analyzer to check for syntactical errors.
 * All methods are assuming Lexical Analyzer found no illegal tokens.
 * Sends tokens to Semantic Analyzer if no errors found, otherwise exits program 
 * and no output file is created.
 * 
 * @author Michelle D'Apice
 */

public class MySyntaxAnalyzer implements SyntaxAnalyzer {	
	
	//creating object to have access to Lexical Analyzer class
	static MyLexicalAnalyzer Lexer = new MyLexicalAnalyzer();
	
	
	/**
	 * This method implements the BNF grammar rule for the document annotation.
	 * 
	 * Checks the beginning and end tags of the document.
	 * Sends to additional method to decide next path.
	 * Ensures there are no annotations after the end tag.
	 * 
	 * If error is found, program is exited.
	 */
	@Override
	public void lolcode() {
		//**start state
		//everything must start with #HAI
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			Lexer.getNextToken();
			code(); //send to to decide next path
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_END)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//**interprets last space as a character - if it doesn't do that on your computer, it should work
				//get next token
				/*Lexer.getNextToken();
				//check end of doc
				if(!MyCompiler.token.equals(" ")){
					System.err.println("SYNTAX ERROR: No annotations allowed after the " + LexicalTokens.DOC_END + " tag.");
					System.exit(0);
				}*/
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token + " when " + LexicalTokens.DOC_END + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " when " + LexicalTokens.DOC_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of lolcode
	
	/**
	 * This method determines the path by peeking ahead at the next token.
	 * 
	 * Sends to other methods depending on next token.
	 * If the current token does not match any of the paths specified here, then there is a Syntax Error.
	 * If error is found, program is exited.
	 */
	public void code(){
		//decide path based on first token
		//variable
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VAR_BEGIN)){
			define();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)){
				head();
				body();
			}
			else{
				body();
			}
		}
		//head
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)){
			head();
			define();
			body();
		}
		//comment
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			comment();
			define();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)){
				head();
				body();
			}
			else{
				body();
			}
		}
		//body
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARA_BEGIN) || MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITAL_BEGIN)
				|| MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN) || MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)
				|| !(MyCompiler.token.charAt(0) == '#')){
			body();
		}
		//must follow one of these patterns
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " placed in this position does not follow the grammar for this language.");
			System.exit(0);
		}
	}
	
	/**
	 * This method processes all of the tokens that are just plaintext until another tag is reached.
	 */
	public void text() {
		MyCompiler.parseTree.add(MyCompiler.token);
		char first = MyCompiler.token.charAt(0); //if first character is a # it is a tag, otherwise it is text
		while(!(first == '#')){
			Lexer.getNextToken();
			first = MyCompiler.token.charAt(0);
		}
	}//end of text method
	
	/**
	 * This method implements the BNF grammar rule for the nonterminal body.
	 * 
	 * Sends to other methods depending on next token.
	 * If no match is found it will return to the method which called it.
	 */
	public void body() {
		//comment
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			comment();
			body();
		}
		//paragraph
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARA_BEGIN)){
			paragraph();
			body();
		}
		//bold
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			body();
		}
		//italics
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITAL_BEGIN)){
			italics();
			body();
		}
		//list
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			body();
		}
		//any annotations in inner-text nonterminal/if it's not a tag it is text
		else if(LexicalTokens.innertextList.contains(MyCompiler.token.toUpperCase()) || !(MyCompiler.token.charAt(0) == '#')){
			innerText();
			body();
		}
	}//end of body method

	/**
	 * This method implements the BNF grammar rule for the comment annotation.
	 * 
	 * Checks the beginning and end tags for a comment annotation.
	 * Sends to the text() method after the beginning tag to process the text of the comment.
	 * If error is found, the program is exited.
	 */
	@Override
	public void comment() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.TLDR)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.TLDR + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.COMMENT_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of comment method
	
	/**
	 * This method implements the BNF grammar rule for the head annotation.
	 * 
	 * Checks the beginning and end tags for the head annotation.
	 * Sends to the title() method after the beginning tag to check the syntax of the title within the head annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void head() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			//check for title
			title();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.OIC)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.OIC + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.HEAD_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of head method
	
	/**
	 * This method implements the BNF grammar rule for the title annotation.
	 * 
	 * Checks the beginning and end tags of the title annotation.
	 * Sends to the text() method after the beginning tag to process the text of the title.
	 * If error is found, program is exited.
	 */
	@Override
	public void title() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.TITLE_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.TITLE_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of title method

	/**
	 * This method implements the BNF grammar rule for the paragraph annotation.
	 * 
	 * Checks the beginning and end tags of the paragraph annotation.
	 * Sends to define() and innerPara() methods after beginning tag, to check for any variable
	 * definitions and to check for any additional annotations that could be within a paragraph.
	 * If error is found, program is exited.
	 */
	@Override
	public void paragraph() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARA_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			//check for variables
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VAR_BEGIN)){
				define();
			}
			innerPara();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.OIC)){
				//add to parse tree 
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.OIC + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.PARA_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of paragraph method
	
	/**
	 * This method implements the BNF grammar rule for the inner-paragraph nonterminal.
	 * 
	 * Sends to other methods depending on next token.
	 * If no match is found it will return to the method which called it.
	 */
	public void innerPara() {
		//bold
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			innerPara();
		}
		//italics
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITAL_BEGIN)){
			italics();
			innerPara();
		}
		//list
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			innerPara();
		}
		//newline
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			newline();
			innerPara();
		}
		//any annotations in inner-text nonterminal/if it's not a tag it is text
		else if(LexicalTokens.innertextList.contains(MyCompiler.token.toUpperCase()) || !(MyCompiler.token.charAt(0) == '#')){
			innerText();
			innerPara();
		}
	}//end of innerPara method
	
	/**
	 * This method implements the BNF grammar rule for the inner-text nonterminal.
	 * 
	 * Sends to other methods depending on next token.
	 * If no match is found it will return to the method which called it.
	 */
	public void innerText() {
		//visible
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VISIBLE)){
			use();
			innerText();
		}
		//newline
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			newline();
			innerText();
		}
		//audio
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUND_BEGIN)){
			audio();
			innerText();
		}
		//video
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VID_BEGIN)){
			video();
			innerText();
		}
		//if it's not any annotations in inner-text nonterminal/if it's not a tag then it is text
		else if(!(LexicalTokens.innertextList.contains(MyCompiler.token.toUpperCase())) && !(MyCompiler.token.charAt(0) == '#')){
			text();
			innerText();
		}
	}//end of innerText method
	
	/**
	 * This method implements the BNF grammar rule for the newline annotation.
	 * 
	 * Checks the beginning tag of the newline annotation.
	 * Since there are no other annotations that go along with this rule,
	 * the method only calls itself again to check for the presence of multiple
	 * newline annotations.
	 */
	public void newline() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			newline();
		}
	}//end of newline method

	/**
	 * This method implements the BNF grammar rule for the bold annotation.
	 * 
	 * Checks the beginning and end tags for the bold annotation.
	 * Sends to define() and innerText() methods after beginning tag, to check for any variable
	 * definitions and to check for any additional annotations that could be within a bold annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void bold() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			//check for variables
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VAR_BEGIN)){
				define();
			}
			innerText();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.BOLD_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of bold method

	/**
	 * This method implements the BNF grammar rule for the italics annotation.
	 * 
	 * Checks the beginning and end tags for the italics annotation.
	 * Sends to define() and innerText() methods after beginning tag, to check for any variable
	 * definitions and to check for any additional annotations that could be within an italics annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void italics() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITAL_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			//check for variables
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VAR_BEGIN)){
				define();
			}
			innerText();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.ITAL_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of italics method

	/**
	 * This method implements the BNF grammar rule for the item annotation.
	 * 
	 * Checks the beginning and end tags for the list annotation, as well as the beginning and end tags
	 * for at least one list-item annotation.
	 * Sends to innerList() method to check for additional annotations that could be within a list annotation.
	 * After at least one item is checked with no errors, sends to item() method to check for any additonal items within the list.
	 * If error is found, program is exited.
	 */
	@Override
	public void list() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
				innerList();
				if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
					//add to parse tree
					MyCompiler.parseTree.add(MyCompiler.token);
					//get next token
					Lexer.getNextToken();
				}
				else{
					System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
					System.exit(0);
				}
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.ITEM_BEGIN + " was expected.");
				System.exit(0);
			}
			
			//more list items?
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
				item();
			}
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.OIC)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.OIC + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.LIST_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of list method
	
	/**
	 * This method implements the BNF grammar rule for the inner-list nonterminal.
	 * 
	 * Sends to other methods depending on next token.
	 * If no match is found it will return to the method which called it.
	 */
	public void innerList() {
		//bold
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			innerList();
		}
		//italics
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITAL_BEGIN)){
			italics();
			innerList();
		}
		//list
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			innerList();
		}
		//any annotations in inner-text nonterminal/if it's not a tag it is text
		else if(LexicalTokens.innertextList.contains(MyCompiler.token.toUpperCase()) || !(MyCompiler.token.charAt(0) == '#')){
			innerText();
			innerList();
		}
	}//end of innerList method

	/**
	 * This method implements the BNF grammar rule for the item annotation.
	 * 
	 * Checks the beginning and end tags for the item annotation.
	 * Sends to innerList() method after beginning tag, to check for any additional annotations that could be within an item annotation.
	 * After at least one item is checked with no errors, re-sends to item method to check for any additonal items.
	 * If error is found, program is exited.
	 */
	@Override
	public void item() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			innerList();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
			
			//more items?
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)) item();
		}
		else{
			System.err.println("BLAH SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.ITEM_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of item method

	/**
	 * This method implements the BNF grammar rule for the audio annotation.
	 * 
	 * Checks the beginning and end tags for the audio annotation.
	 * Sends to text() method after beginning tag to process text within annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void audio() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUND_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.SOUND_BEGIN + " was expected.");
			System.exit(0);
		}
	}//end of audio method

	/**
	 * This method implements the BNF grammar rule for the video annotation.
	 * 
	 * Checks the beginning and end tags for the video annotation.
	 * Sends to text() method after beginning tag to process text within annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void video() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VID_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.VID_BEGIN + " was expected.");
			System.exit(0);
		}

	}//end of video method

	/**
	 * This method implements the BNF grammar rule for the define annotation.
	 * 
	 * Checks the beginning and end tags for the define annotation.
	 * Sends to text() method after beginning tag and after middle tag to process text within annotation.
	 * After at least one variable definition is checked with no errors, re-sends to define() to check if there are
	 * any additional variable definitions.
	 * If error is found, program is exited.
	 */
	@Override
	public void define() { 
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VAR_BEGIN)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITZ)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
				text();
				if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
					//add to parse tree
					MyCompiler.parseTree.add(MyCompiler.token);
					//get next token
					Lexer.getNextToken();
					define();
				}
				else{
					System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
					System.exit(0);
				}
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.ITZ + " was expected.");
				System.exit(0);
			}
		}
	}//end of define method

	/**
	 * This method implements the BNF grammar rule for the use annotation.
	 * 
	 * Checks the beginning and end tags for the use annotation.
	 * Sends to text() method after beginning tag to process text within annotation.
	 * If error is found, program is exited.
	 */
	@Override
	public void use() {
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VISIBLE)){
			//add to parse tree
			MyCompiler.parseTree.add(MyCompiler.token);
			//get next token
			Lexer.getNextToken();
			text();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.MKAY)){
				//add to parse tree
				MyCompiler.parseTree.add(MyCompiler.token);
				//get next token
				Lexer.getNextToken();
			}
			else{
				System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.MKAY + " was expected.");
				System.exit(0);
			}
		}
		else{
			System.err.println("SYNTAX ERROR: " + MyCompiler.token +  " when " + LexicalTokens.VISIBLE + " was expected.");
			System.exit(0);
		}
	}//end of use method

}//end of public class MySyntaxAnalyzer